package com.luom.fsp.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.luom.fsp.annotation.AuthCheck;
import com.luom.fsp.common.BaseResponse;
import com.luom.fsp.common.DeleteRequest;
import com.luom.fsp.common.ErrorCode;
import com.luom.fsp.common.ResultUtils;
import com.luom.fsp.constant.UserConstant;
import com.luom.fsp.exception.BusinessException;
import com.luom.fsp.exception.ThrowUtils;
import com.luom.fsp.model.dto.order.*;
import com.luom.fsp.model.entity.Order;
import com.luom.fsp.model.entity.User;
import com.luom.fsp.model.vo.OrderPriceVO;
import com.luom.fsp.model.vo.OrderVO;
import com.luom.fsp.service.OrderService;
import com.luom.fsp.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * 订单接口
 *
*/
@RestController
@RequestMapping("/order")
@Slf4j
public class OrderController {

    @Resource
    private OrderService orderService;

    @Resource
    private UserService userService;

    // region 增删改查

    /**
     * 创建订单
     *
     * @param orderAddRequest
     * @param request
     * @return
     */
    @PostMapping("/add")
    public BaseResponse<Long> addOrder(@RequestBody OrderAddRequest orderAddRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(orderAddRequest == null, ErrorCode.PARAMS_ERROR);
        long newOrderId = orderService.addOrder(orderAddRequest, request);
        return ResultUtils.success(newOrderId);
    }

    /**
     * 计算订单价格
     */
    @GetMapping("/price")
    public BaseResponse<OrderPriceVO> getOrderPrice(@RequestParam Long couponId,
                                                    @RequestParam Integer money) {
        OrderPriceVO orderPrice =orderService.getOrderPrice(couponId, money);
        return ResultUtils.success(orderPrice);
    }

    /**
     * 删除订单
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteOrder(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User user = userService.getLoginUser(request);
        long id = deleteRequest.getId();
        // 判断是否存在
        Order oldOrder = orderService.getById(id);
        ThrowUtils.throwIf(oldOrder == null, ErrorCode.NOT_FOUND_ERROR);
        // 仅本人或管理员可删除
        if (!oldOrder.getUserId().equals(user.getId()) && !userService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        // 操作数据库
        boolean result = orderService.removeById(id);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }

    /**
     * 更新订单（仅管理员可用）
     *
     * @param orderUpdateRequest
     * @return
     */
    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateOrder(@RequestBody OrderUpdateRequest orderUpdateRequest) {
        if (orderUpdateRequest == null || orderUpdateRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // todo 在此处将实体类和 DTO 进行转换
        Order order = new Order();
        BeanUtils.copyProperties(orderUpdateRequest, order);
        // 数据校验
        orderService.validOrder(order, false);
        // 判断是否存在
        long id = orderUpdateRequest.getId();
        Order oldOrder = orderService.getById(id);
        ThrowUtils.throwIf(oldOrder == null, ErrorCode.NOT_FOUND_ERROR);
        // 操作数据库
        boolean result = orderService.updateById(order);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }

    /**
     * 根据 id 获取订单（封装类）
     *
     * @param id
     * @return
     */
    @GetMapping("/get/vo")
    public BaseResponse<OrderVO> getOrderVOById(long id, HttpServletRequest request) {
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        // 查询数据库
        Order order = orderService.getById(id);
        ThrowUtils.throwIf(order == null, ErrorCode.NOT_FOUND_ERROR);
        // 获取封装类
        return ResultUtils.success(orderService.getOrderVO(order, request));
    }

    /**
     * 分页获取订单列表（仅管理员可用）
     *
     * @param orderQueryRequest
     * @return
     */
    @PostMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<Order>> listOrderByPage(@RequestBody OrderQueryRequest orderQueryRequest) {
        long current = orderQueryRequest.getCurrent();
        long size = orderQueryRequest.getPageSize();
        // 查询数据库
        Page<Order> orderPage = orderService.page(new Page<>(current, size),
                orderService.getQueryWrapper(orderQueryRequest));
        return ResultUtils.success(orderPage);
    }

    /*@PostMapping("/list/page/vo")
    public BaseResponse<Page<OrderVO>> listOrderVOByPage(@RequestBody OrderAllQueryRequest orderAllQueryRequest,
                                                               HttpServletRequest request) {
        return ResultUtils.success(orderService.listOrderVOByPage(orderAllQueryRequest,request));
    }*/

    /**
     * 分页获取订单列表（封装类）
     *
     * @param request
     * @return
     */
    @PostMapping("/list/page/vo")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<OrderVO>> listOrderVOByPage(@RequestBody OrderAllQueryRequest orderAllQueryRequest,
                                                         HttpServletRequest request) {
        return ResultUtils.success(orderService.listOrderVOByPage(orderAllQueryRequest,request));
    }

    /**
     * 分页获取当前登录用户创建的订单列表
     *
     * @param orderQueryRequest
     * @param request
     * @return
     */
    @PostMapping("/my/list/page/vo")
    public BaseResponse<Page<OrderVO>> listMyOrderVOByPage(@RequestBody OrderQueryRequest orderQueryRequest,
                                                                 HttpServletRequest request) {
        ThrowUtils.throwIf(orderQueryRequest == null, ErrorCode.PARAMS_ERROR);
        // 补充查询条件，只查询当前登录用户的数据
        User loginUser = userService.getLoginUser(request);
        orderQueryRequest.setUserId(loginUser.getId());
        long current = orderQueryRequest.getCurrent();
        long size = orderQueryRequest.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
        // 查询数据库
        Page<Order> orderPage = orderService.page(new Page<>(current, size),
                orderService.getQueryWrapper(orderQueryRequest));
        // 获取封装类
        return ResultUtils.success(orderService.getOrderVOPage(orderPage, request));
    }

    /**
     * 编辑订单（给用户使用）
     *
     * @param orderEditRequest
     * @param request
     * @return
     */
    @PostMapping("/edit")
    public BaseResponse<Boolean> editOrder(@RequestBody OrderEditRequest orderEditRequest, HttpServletRequest request) {
        if (orderEditRequest == null || orderEditRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Order order = new Order();
        BeanUtils.copyProperties(orderEditRequest, order);
        // 数据校验
        orderService.validOrder(order, false);
        User loginUser = userService.getLoginUser(request);
        // 判断是否存在
        long id = orderEditRequest.getId();
        Order oldOrder = orderService.getById(id);
        ThrowUtils.throwIf(oldOrder == null, ErrorCode.NOT_FOUND_ERROR);
        // 仅本人或管理员可编辑
        if (!oldOrder.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        // 操作数据库
        boolean result = orderService.updateById(order);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }

    // endregion

    // region 订单操作

    /**
     * 订单支付
     * @param orderOperationRequest
     * @param request
     * @return
     */
    @PostMapping("/pay")
    public BaseResponse<Boolean> payOrder(@RequestBody OrderOperationRequest orderOperationRequest, HttpServletRequest request) {
        if (orderOperationRequest == null || orderOperationRequest.getId() <= 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "订单不存在");
        }
        return ResultUtils.success(orderService.payOrder(orderOperationRequest, request));
    }

    /**
     * 订单确认收货
     * @param orderOperationRequest
     * @param request
     * @return
     */
    @PostMapping("/confirm-receipt")
    public BaseResponse<Boolean> confirmReceipt(@RequestBody OrderOperationRequest orderOperationRequest, HttpServletRequest request) {
        if (orderOperationRequest == null || orderOperationRequest.getId() <= 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "订单不存在");
        }
        return ResultUtils.success(orderService.confirmReceipt(orderOperationRequest, request));
    }

    /**
     * 取消订单
     * @param orderOperationRequest
     * @param request
     * @return
     */
    @PostMapping("/cancel")
    public BaseResponse<Boolean> cancelOrder(@RequestBody OrderOperationRequest orderOperationRequest, HttpServletRequest request) {
        if (orderOperationRequest == null || orderOperationRequest.getId() <= 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "订单不存在");
        }
        return ResultUtils.success(orderService.cancelOrder(orderOperationRequest, request));
    }

    /**
     * 退款
     */
    @PostMapping("/refund")
    public BaseResponse<String> refundOrder(@RequestBody OrderOperationRequest orderOperationRequest, HttpServletRequest request) {
        if (orderOperationRequest == null || orderOperationRequest.getId() <= 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "订单不存在");
        }
        boolean result = orderService.refundOrder(orderOperationRequest, request);
        if (!result) {
            return ResultUtils.success("退款已申请，待审核");
        }else {
            // TODO 消息通知模块
            return ResultUtils.success("退款成功");
        }
    }

    /**
     * 发货
     */
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @PostMapping("/deliver")
    public BaseResponse<Boolean> deliverOrder(@RequestBody OrderOperationRequest orderOperationRequest, HttpServletRequest request) {
        if (orderOperationRequest == null || orderOperationRequest.getId() <= 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "订单不存在");
        }
        return ResultUtils.success(orderService.deliverOrder(orderOperationRequest, request));
    }

    /**
     * 批量生成订单，并结算
     */
    @PostMapping("/add/batch")
    public BaseResponse<Boolean> addOrderBatch(@RequestBody OrderAddBatchRequest orderAddBatchRequest, HttpServletRequest request) {
        if (orderAddBatchRequest == null  || orderAddBatchRequest.getCartIds().isEmpty()){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "订单不存在");
        }
        return ResultUtils.success(orderService.addOrderBatch(orderAddBatchRequest, request));
    }

    // endregion
}
